package com.example.websocket.another.web;

import com.example.websocket.another.dto.NotifyBean;
import com.example.websocket.another.dto.UserVo;
import com.example.websocket.another.entity.UserEntity;
import com.example.websocket.another.service.UserMessageService;
import com.example.websocket.another.service.UserService;
import com.example.websocket.another.utils.SocketMessageUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.time.LocalTime;


@Controller
@RequestMapping(value = "/webSocket")
@Slf4j
public class WebSocketController {

    @Autowired
    private SimpMessagingTemplate simpMessagingTemplate;
    @Autowired
    private UserMessageService userMessageService;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private UserService userService;

    public static final String WEB_SC_TOPIC_NOTIFY = "/topic/greetings";
    public static final long ADMIN = 0L;

    @RequestMapping(value = "/sendMsg")
    @ResponseBody
    public void sendMsg() {
        log.info("测试主动发送消息");
        String message = "服务器给你发消息啦！" + LocalTime.now();
        UserEntity userEntity = userService.getOne(ADMIN);
        NotifyBean notifyBean = NotifyBean.builder().content(message).sender(userEntity.getUserName()).build();
        // 保存离线用户的未接收到消息
        userMessageService.saveAllMissMessage(UserVo.builder().from(userEntity.getId() + "").message(message).build());
        simpMessagingTemplate.convertAndSend(WEB_SC_TOPIC_NOTIFY, notifyBean);
    }


    @RequestMapping(value = "/token")
    @ResponseBody
    public Object sendMsg(String username) {
        return userService.getUserIdByName(username);
    }


    /**
     * 当前用户 -》发送所有人
     * 请求路径 /app/test/testAll
     * 接收路径 /topic/greetings
     * <p>
     * 当浏览器向服务端发送请求时,通过@MessageMapping映射/welcome这个地址,类似于@ResponseMapping
     * 当服务器有消息时,会对订阅了@SendTo中的路径的浏览器发送消息
     *
     * @param userVo
     * @return
     */
    @MessageMapping("/test/testAll")
    @SendTo(WEB_SC_TOPIC_NOTIFY)
    public NotifyBean test(UserVo userVo) {
        // 保存离线用户的未接收到消息
        userMessageService.saveAllMissMessage(userVo);
        return NotifyBean.builder().content("Send all person！" + userVo.getMessage()).sender(userService.getUserName(userVo.getFrom())).build();
    }


    /**
     * 点对点发送消息demo
     * 根据用户key发送消息
     * *  请求路径 /app/test/toOne
     * *   接收路径 /user/topic/greetings
     * convertAndSendToUser该方法会在订阅路径前拼接"/user"，所以前端订阅的路径全路径是"/user/topic/notify"
     *
     * @param userVo
     * @return
     */
    @MessageMapping("/test/toOne")
    public void toOne(UserVo userVo) {
        String sessionId = (String) redisTemplate.opsForValue().get("websocket:" + userVo.getId());
        if (sessionId == null) {
            log.error("用户唯一标识：{}，session 标识为获取到", userVo);
            return;
        }
        NotifyBean notifyBean;
        if (StringUtils.isEmpty(userVo.getFrom())) {
            //只发送给自己
            notifyBean = NotifyBean.builder().content("only Send to me:" + userVo.getMessage()).sender(userService.getUserName(userVo.getId())).build();
            simpMessagingTemplate.convertAndSendToUser(sessionId, WEB_SC_TOPIC_NOTIFY, notifyBean, SocketMessageUtil.createHeaders(sessionId));
        } else {
            //发送别人
            notifyBean = NotifyBean.builder().content("Send to you:" + userVo.getMessage()).sender(userService.getUserName(userVo.getFrom())).build();
            simpMessagingTemplate.convertAndSendToUser(sessionId, WEB_SC_TOPIC_NOTIFY, notifyBean, SocketMessageUtil.createHeaders(sessionId));

            //发送自己
            String sessionFrom = (String) redisTemplate.opsForValue().get("websocket:" + userVo.getFrom());
            if (sessionFrom == null) {
                log.error("用户唯一标识：{}，session 标识为获取到", userVo);
                return;
            }
            NotifyBean notifyBean2 = NotifyBean.builder().content("i say:" + userVo.getMessage()).sender(userService.getUserName(userVo.getFrom())).build();
            simpMessagingTemplate.convertAndSendToUser(sessionFrom, WEB_SC_TOPIC_NOTIFY, notifyBean2, SocketMessageUtil.createHeaders(sessionFrom));
        }
    }


}